/* 
 * This program is free software; you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; either version 3 of the License, or 
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 * for more details.
 * 
 * You should have received a copy of the GNU General Public License along 
 * with this program; if not, write to the Free Software Foundation, Inc., 
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <QCoreApplication>
#include <QBuffer>
#include <stdint.h>

#include "raranalyzer.h"

#include "log.h"

namespace Wishmaster
{
	RarAnalyzer::RarAnalyzer() : Analyzer()
	{
		m_signature = QByteArray("\x52\x61\x72\x21\x1a\x07\x00", 7);
	}

	RarAnalyzer::~RarAnalyzer()
	{
	}

	int RarAnalyzer::probe(const QByteArray& arr)
	{
		return arr.indexOf(m_signature);
	}

	ExtraInfo RarAnalyzer::obtain(const QByteArray& arr)
	{
		ExtraInfo info;
		int pos = probe(arr);
		if(pos > 0)
		{
			log(llDebug, "RARJPG detected\n\r");
			info.id = "rar";
			QBuffer buf(const_cast<QByteArray*>(&arr));
			buf.open(QIODevice::ReadOnly);
			buf.seek(pos + 7); // +7 is for signature
			int filecount = 0;
			while(!buf.atEnd())
			{
				uint16_t crc, flags, size;
				uint8_t type;
				buf.read((char*)&crc, 2);
				buf.read((char*)&type, 1);
				buf.read((char*)&flags, 2);
				buf.read((char*)&size, 2);
				log(llDebug, "RarAnalyzer: chunk 0x%02x", type);
				if((type < 0x72) || (type > 0x7a)) // Valid RAR types
				{
					break;
				}
				if(type == 0x74) // File chunk
				{
					uint32_t filesize;
					buf.read((char*)&filesize, 4);
					buf.seek(buf.pos() + size - 11 + filesize);
					filecount++;
				}
				else
				{
					buf.seek(buf.pos() + size - 7);
				}
			}
			int endpos = buf.pos();
			if(!buf.atEnd())
				endpos -= 7; // We read extra crc, type, flags, size, that's 7 bytes
			log(llDebug, "Length = %d", endpos - pos + 1);
			info.position = pos;
			info.data = arr.mid(pos, endpos - pos + 1);
			info.description = qApp->translate("RarAnalyzer", "This image contains a RAR archive with %1 files.").arg(filecount);
			info.fileext = "rar";
			info.type = "Rar archive";
			info.saveable = true;
		}
		return info;
	}
}

